package org.mybatis.generator.codegen.mybatis3.controller;

import static org.mybatis.generator.internal.util.StringUtility.stringHasValue;
import static org.mybatis.generator.internal.util.messages.Messages.getString;

import java.util.ArrayList;
import java.util.List;

import org.mybatis.generator.api.CommentGenerator;
import org.mybatis.generator.api.dom.java.CompilationUnit;
import org.mybatis.generator.api.dom.java.Field;
import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
import org.mybatis.generator.api.dom.java.JavaVisibility;
import org.mybatis.generator.api.dom.java.TopLevelClass;
import org.mybatis.generator.codegen.AbstractJavaClientGenerator;
import org.mybatis.generator.codegen.AbstractXmlGenerator;
import org.mybatis.generator.codegen.mybatis3.controller.elements.AbstractJavaControllerMethodGenerator;
import org.mybatis.generator.codegen.mybatis3.controller.elements.AddMethodControllerGenerator;
import org.mybatis.generator.codegen.mybatis3.controller.elements.AddShowMethodControllerGenerator;
import org.mybatis.generator.codegen.mybatis3.controller.elements.DeleteMethodControllerGenerator;
import org.mybatis.generator.codegen.mybatis3.controller.elements.DetailShowMethodControllerGenerator;
import org.mybatis.generator.codegen.mybatis3.controller.elements.SearchMethodControllerGenerator;
import org.mybatis.generator.codegen.mybatis3.controller.elements.UpdateMethodControllerGenerator;
import org.mybatis.generator.codegen.mybatis3.controller.elements.UpdateShowMethodControllerGenerator;
import org.mybatis.generator.codegen.mybatis3.xmlmapper.XMLMapperGenerator;
import org.mybatis.generator.config.PropertyRegistry;

/**
 * controller构造类
 *
 * @author tangdelong
 * 2015年5月24日
 */
public class JavaControllerGenerator extends AbstractJavaClientGenerator {
	 /**
     * 
     */
    public JavaControllerGenerator() {
        super(true);
    }

    public JavaControllerGenerator(boolean requiresMatchedXMLGenerator) {
        super(requiresMatchedXMLGenerator);
    }
    
    @Override
    public List<CompilationUnit> getCompilationUnits() {
        progressCallback.startTask(getString("Progress.17", //$NON-NLS-1$
                introspectedTable.getFullyQualifiedTable().toString()));
        CommentGenerator commentGenerator = context.getCommentGenerator();

        FullyQualifiedJavaType parentType = new FullyQualifiedJavaType(
                introspectedTable.getBaseRecordType());
        
        FullyQualifiedJavaType type = new FullyQualifiedJavaType(introspectedTable.getMyBatis3JavaControllerType());
        TopLevelClass topLevelClass = new TopLevelClass(type);
        List<String> classAnnotationLs = new ArrayList<String>();
        classAnnotationLs.add("Controller");
        classAnnotationLs.add("RequestMapping(\"/"+parentType.getInjectName()+"\")");
        topLevelClass.setAnnotationNames(classAnnotationLs);
        
        
        topLevelClass.setVisibility(JavaVisibility.PUBLIC);
        commentGenerator.addJavaFileComment(topLevelClass);
        
        // 类加注释
        commentGenerator.addClassComment(topLevelClass, introspectedTable,"controller");

        String rootInterface = introspectedTable
            .getTableConfigurationProperty(PropertyRegistry.ANY_ROOT_INTERFACE);
        if (!stringHasValue(rootInterface)) {
            rootInterface = context.getJavaClientGeneratorConfiguration()
                .getProperty(PropertyRegistry.ANY_ROOT_INTERFACE);
        }

        
        // java import 类添加
        topLevelClass.addImportedType("org.springframework.web.servlet.ModelAndView");
        topLevelClass.addImportedType("org.springframework.web.bind.annotation.RequestMapping");
        topLevelClass.addImportedType("org.springframework.web.bind.annotation.RequestParam");
        topLevelClass.addImportedType("org.springframework.stereotype.Controller");
        topLevelClass.addImportedType("javax.servlet.http.HttpServletRequest");
        topLevelClass.addImportedType("java.util.List");
        topLevelClass.addImportedType("com.github.pagehelper.PageHelper");
//        topLevelClass.addImportedType("portal.utils.PageInfo");
        topLevelClass.addImportedType(introspectedTable.getBaseRecordConditionType());
        topLevelClass.addImportedType(introspectedTable.getBaseRecordType());
        
        
        // 获取service类
        FullyQualifiedJavaType service = new FullyQualifiedJavaType(introspectedTable.getMyBatis3JavaServiceType());
        
        // 注入service
        Field field = new Field();
        field.setVisibility(JavaVisibility.PRIVATE);
        field.setType(service);
        field.setName(service.getInjectName());
        List<String> strLs = new ArrayList<String>();
        strLs.add("Autowired");
        field.setAnnotationNames(strLs);
        topLevelClass.addImportedType("org.springframework.beans.factory.annotation.Autowired");
        
        topLevelClass.addField(field);
        topLevelClass.addImportedType(service);
        
        
        // Controller中方法添加
        searchMethod(topLevelClass);
        addShowMethod(topLevelClass);
        addMethod(topLevelClass);
        updateShowMethod(topLevelClass);
        updateMethod(topLevelClass);
        deleteMethod(topLevelClass);
        detailShowMethod(topLevelClass);

        List<CompilationUnit> answer = new ArrayList<CompilationUnit>();
        answer.add(topLevelClass);
        
        List<CompilationUnit> extraCompilationUnits = getExtraCompilationUnits();
        if (extraCompilationUnits != null) {
            answer.addAll(extraCompilationUnits);
        }

        return answer;
    }



    protected void addShowMethod(TopLevelClass topLevelClass){
    	AbstractJavaControllerMethodGenerator generator = new AddShowMethodControllerGenerator();
    	initializeAndExecuteGenerator(generator,topLevelClass);
    }
    
    protected void addMethod(TopLevelClass topLevelClass){
    	AbstractJavaControllerMethodGenerator generator = new AddMethodControllerGenerator();
    	initializeAndExecuteGenerator(generator,topLevelClass);
    }
    
    protected void deleteMethod(TopLevelClass topLevelClass){
    	AbstractJavaControllerMethodGenerator generator = new DeleteMethodControllerGenerator();
    	initializeAndExecuteGenerator(generator,topLevelClass);
    }
    
    protected void detailShowMethod(TopLevelClass topLevelClass){
    	AbstractJavaControllerMethodGenerator generator = new DetailShowMethodControllerGenerator();
    	initializeAndExecuteGenerator(generator,topLevelClass);
    }
    
    protected void searchMethod(TopLevelClass topLevelClass){
    	AbstractJavaControllerMethodGenerator generator = new SearchMethodControllerGenerator();
    	initializeAndExecuteGenerator(generator,topLevelClass);
    }
    
    protected void updateShowMethod(TopLevelClass topLevelClass){
    	AbstractJavaControllerMethodGenerator generator = new UpdateShowMethodControllerGenerator();
    	initializeAndExecuteGenerator(generator,topLevelClass);
    }
    
    protected void updateMethod(TopLevelClass topLevelClass){
    	AbstractJavaControllerMethodGenerator generator = new UpdateMethodControllerGenerator();
    	initializeAndExecuteGenerator(generator,topLevelClass);
    }

    protected void initializeAndExecuteGenerator(
    		AbstractJavaControllerMethodGenerator methodGenerator,
            TopLevelClass topLevelClass) {
        methodGenerator.setContext(context);
        methodGenerator.setIntrospectedTable(introspectedTable);
        methodGenerator.setProgressCallback(progressCallback);
        methodGenerator.setWarnings(warnings);
        methodGenerator.addControllerElements(topLevelClass);
    }

    public List<CompilationUnit> getExtraCompilationUnits() {
        return null;
    }

    @Override
    public AbstractXmlGenerator getMatchedXMLGenerator() {
        return new XMLMapperGenerator();
    }
}
